package org.ztest.executor;

/**
 * 
 * @author lhl
 *
 * 2015年8月21日下午3:17:50
 */
public class Looper
{
	static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
	final MessageQueue mQueue;
	final Thread thread;
	
	private Looper(boolean quitAllowed)
	{
		mQueue = new MessageQueue(quitAllowed);
		thread = Thread.currentThread();
	}
	
	public void quit()
	{
		mQueue.quit(false);
	}
	
	public void quitSafely()
	{
		mQueue.quit(true);
	}
	
	public static void prepare()
	{
		prepare(true);
	}
	
	private static void prepare(boolean quitAllowed)
	{
		if (sThreadLocal.get() != null)
			throw new RuntimeException("Only one Looper can be created per thread!");
		
		sThreadLocal.set(new Looper(quitAllowed));
	}
	
    public static Looper myLooper()
    {
        return sThreadLocal.get();
    }
	
	public static void loop() throws InterruptedException
	{
		final Looper me = myLooper();
		if (me == null)
			throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
		
		final MessageQueue queue = me.mQueue;
		
		for (;;)
		{
			Message msg = queue.next();
			if (msg == null)
				return;
			
			msg.target.run();
		}
	}
}
